package dropdown

import (
	"context"
	"github.com/templui/templui/internal/components/popover"
	"github.com/templui/templui/internal/utils"
)

type Placement = popover.Placement

const (
	PlacementTop         = popover.PlacementTop
	PlacementTopStart    = popover.PlacementTopStart
	PlacementTopEnd      = popover.PlacementTopEnd
	PlacementRight       = popover.PlacementRight
	PlacementRightStart  = popover.PlacementRightStart
	PlacementRightEnd    = popover.PlacementRightEnd
	PlacementBottom      = popover.PlacementBottom
	PlacementBottomStart = popover.PlacementBottomStart
	PlacementBottomEnd   = popover.PlacementBottomEnd
	PlacementLeft        = popover.PlacementLeft
	PlacementLeftStart   = popover.PlacementLeftStart
	PlacementLeftEnd     = popover.PlacementLeftEnd
)

type contextKey string

var (
	contentIDKey    contextKey = "contentID"
	subContentIDKey contextKey = "subContentID"
)

type Props struct {
	ID string
}

type TriggerProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type ContentProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
	Placement  Placement
}

type GroupProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type LabelProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type ItemProps struct {
	ID           string
	Class        string
	Attributes   templ.Attributes
	Disabled     bool
	Href         string
	Target       string
	PreventClose bool
}

type SeparatorProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type ShortcutProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type SubProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type SubTriggerProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type SubContentProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type PortalProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

templ Dropdown(props ...Props) {
	{{
		var p Props
		if len(props) > 0 {
			p = props[0]
		}
		contentID := p.ID
		if contentID == "" {
			contentID = utils.RandomID()
		}
		ctx = context.WithValue(ctx, contentIDKey, contentID)
	}}
	{ children... }
}

templ Trigger(props ...TriggerProps) {
	{{
		var p TriggerProps
		if len(props) > 0 {
			p = props[0]
		}
		contentID, ok := ctx.Value(contentIDKey).(string)
		if !ok {
			contentID = "fallback-content-id"
		}
	}}
	@popover.Trigger(popover.TriggerProps{
		ID:          p.ID,
		Class:       p.Class,
		Attributes:  p.Attributes,
		For:         contentID,
		TriggerType: popover.TriggerTypeClick,
	}) {
		{ children... }
	}
}

templ Content(props ...ContentProps) {
	{{ var p ContentProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	{{ contentID, ok := ctx.Value(contentIDKey).(string) }}
	if !ok {
		{{ contentID = "fallback-content-id" }} // Must match fallback in Trigger
	}
	{{
		placement := p.Placement
		if placement == "" {
			placement = PlacementBottomStart
		}
	}}
	@popover.Content(popover.ContentProps{
		ID:        contentID,
		Placement: placement,
		Class: utils.TwMerge(
			"z-50 rounded-md bg-popover p-1 shadow-md focus:outline-none overflow-auto",
			"border border-border",
			"min-w-[8rem] max-h-[300px]",
			p.Class,
		),
		Attributes: p.Attributes,
		Exclusive:  true,
	}) {
		{ children... }
	}
}

templ Group(props ...GroupProps) {
	{{ var p GroupProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("py-1", p.Class) }
		role="group"
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Label(props ...LabelProps) {
	{{ var p LabelProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("px-2 py-1.5 text-sm font-semibold", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Item(props ...ItemProps) {
	{{ var p ItemProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	if p.ID == "" {
		{{ p.ID = utils.RandomID() }}
	}
	if p.Href != "" {
		<a
			id={ p.ID }
			if p.Href != "" {
				href={ templ.SafeURL(p.Href) }
			}
			if p.Target != "" {
				target={ p.Target }
			}
			class={
				utils.TwMerge(
					"flex text-left items-center justify-between px-2 py-1.5 text-sm rounded-sm",
					utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
					utils.If(p.Disabled, "opacity-50 pointer-events-none"),
					p.Class,
				),
			}
			role="menuitem"
			data-tui-dropdown-item
			if p.PreventClose {
				data-tui-dropdown-prevent-close="true"
			}
			{ p.Attributes... }
		>
			{ children... }
		</a>
	} else {
		<button
			id={ p.ID }
			class={
				utils.TwMerge(
					"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
					utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
					utils.If(p.Disabled, "opacity-50 pointer-events-none"),
					p.Class,
				),
			}
			role="menuitem"
			data-tui-dropdown-item
			disabled?={ p.Disabled }
			if p.PreventClose {
				data-tui-dropdown-prevent-close="true"
			}
			{ p.Attributes... }
		>
			{ children... }
		</button>
	}
}

templ Separator(props ...SeparatorProps) {
	{{ var p SeparatorProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("h-px my-1 -mx-1 bg-muted", p.Class) }
		role="separator"
		{ p.Attributes... }
	></div>
}

templ Shortcut(props ...ShortcutProps) {
	{{ var p ShortcutProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<span
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("ml-auto text-xs tracking-widest opacity-60", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</span>
}

templ Sub(props ...SubProps) {
	{{
		var p SubProps
		if len(props) > 0 {
			p = props[0]
		}
		subContentID := p.ID
		if subContentID == "" {
			subContentID = utils.RandomID()
		}
		ctx = context.WithValue(ctx, subContentIDKey, subContentID)
	}}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		data-tui-dropdown-submenu
		class={ utils.TwMerge("relative", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ SubTrigger(props ...SubTriggerProps) {
	{{
		var p SubTriggerProps
		if len(props) > 0 {
			p = props[0]
		}
		subContentID, ok := ctx.Value(subContentIDKey).(string)
		if !ok {
			subContentID = "fallback-subcontent-id"
		}
	}}
	@popover.Trigger(popover.TriggerProps{
		ID:          p.ID,
		For:         subContentID,
		TriggerType: popover.TriggerTypeHover,
	}) {
		<button
			type="button"
			data-tui-dropdown-submenu-trigger
			class={
				utils.TwMerge(
					"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
					"focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default",
					p.Class,
				),
			}
			{ p.Attributes... }
		>
			<span>
				{ children... }
			</span>
			<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-auto">
				<path d="M6.5 3L11.5 8L6.5 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
			</svg>
		</button>
	}
}

templ SubContent(props ...SubContentProps) {
	{{
		var p SubContentProps
		if len(props) > 0 {
			p = props[0]
		}
		subContentID, ok := ctx.Value(subContentIDKey).(string)
		if !ok {
			subContentID = "fallback-subcontent-id"
		}
	}}
	@popover.Content(popover.ContentProps{
		ID:            subContentID,
		Placement:     popover.PlacementRightStart,
		Offset:        -4,  // Adjust as needed
		HoverDelay:    100, // ms
		HoverOutDelay: 200, // ms
		Class: utils.TwMerge(
			"z-[9999] min-w-[8rem] rounded-md border bg-popover p-1 shadow-lg",
			p.Class,
		),
		Attributes: p.Attributes,
	}) {
		{ children... }
	}
}
